#!/usr/bin/perl

# Written by André Kugland <kugland@gmail.com>

$help_msg = 
"rename.pl, a script to rename files in batches, using expressions
           of the Perl language to transform it.

Usage:
    rename.pl [options] FILE1 [FILE2 ...]

Where options can be:
    -v                  Verbose.
    -vv                 Very verbose.
    --apply             Really apply modifications.
    -e PERLCODE         Execute PERLCODE. (e.g. 's/a/b/g')
    --from-charset=CS   Source charset. (e.g. \"iso-8859-1\")
    --to-charset=CS     Destination charset. (e.g. \"utf8\")
";

use Getopt::Long;
use Encode;
use Encode::Locale;

Getopt::Long::Configure ("bundling");

# ------------------------------------------------------------------ #
# Our variables.                                                     #
# ------------------------------------------------------------------ #
my $apply = 0;
my $verbose = 0;
my $help = 0;
my $debug = 0;
my @scripts;
my $from_charset = "";
my $to_charset = "";

# ------------------------------------------------------------------ #
# Get cmdline options.                                               #
# ------------------------------------------------------------------ #
$result = GetOptions ("apply" => \$apply,
                      "verbose|v+" => \$verbose,
                      "execute|e=s" => \@scripts,
                      "from-charset=s" => \$from_charset,
                      "to-charset=s", \$to_charset,
                      "help|h|?", \$help,
                      "debug" => \$debug);

if ((($#scripts == -1) && (($from_charset eq "") || ($to_charset eq "")))
    || ($#ARGV == -1) || ($help)) {
	print $help_msg;
	exit(0);
}

# ------------------------------------------------------------------ #
# Composes the filter function using the @scripts array and possibly #
# other options.                                                     #
# ------------------------------------------------------------------ #
$f = "sub filterfunc() {\n\tmy \$s = shift;\n\tfor (\$s) {\n";
$f .= "\t\t$_;\n" foreach (@scripts);	# Get scripts from '-e' opt. #

# Handle charset translation.
$from_charset = "locale_fs" if ($from_charset eq "");
$to_charset = "locale_fs" if ($to_charset eq "");

if ($from_charset ne $to_charset) {
	$f .= "\t\t\$s = encode(\"$to_charset\", "
	    . "decode(\"$from_charset\", \$_));\n";
}

$f .= "\t}\n\treturn \$s;\n}\n";

print "Generated function:\n$f\n" if ($debug);

# ------------------------------------------------------------------ #
# Evaluates the filter function body, so to define it in our scope.  #
# ------------------------------------------------------------------ #
eval $f;

# ------------------------------------------------------------------ #
# Main loop, which passes names through filters and renames files.   #
# ------------------------------------------------------------------ #
foreach (@ARGV) {
	$old_name = $_;
	$new_name = filterfunc($_);

	if ($old_name ne $new_name) {
		if (!$apply or (rename $old_name, $new_name)) {
			print "`$old_name' => `$new_name'\n" if ($verbose);
		} else {
			print "Cannot rename `$old_name' to `$new_name'.\n";
		}
	} else {
		print "`$old_name' unchanged.\n" if ($verbose > 1);
	}
}
